/*
Kakine
ActionScript Framework
Copyright © 2011, PUNY, LLC.

This file is part of KAKINE.

KAKINE is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

KAKINE is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with KAKINE.  If not, see <http://www.gnu.org/licenses/>.
*/ 
package com.puny.mvc.controllers.keyscanner
{
	import com.puny.mvc.controllers.Controller;
	
	import flash.display.DisplayObject;
	import flash.events.KeyboardEvent;
	import flash.ui.Keyboard;
	[Event(name="released", type="com.puny.mvc.controllers.KeyController")]
	/**
	 * $Revision: 795 $ <br/>
	 * Constructs key operations from xml and dispatch the event
	 * which is related to element in the definition xml.
	 */
	public class KeyController extends Controller
	{
		public static const UP:String = "up";
		public static const DOWN:String = "down";
		private var _xml:XML;
		private var _events:Object = new Object();
		private var _keyState:Object = new Object();
		private var _shoot:Boolean = true;
		private var _target:DisplayObject;
		public function KeyController(xml:XML,target:DisplayObject=null)
		{
			_target = target;
			_xml = xml;
		}
		
		override public function beforeReady():void {
			if (_target == null) {
				_target = stage;
			}
			_target.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			_target.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			var char:int
			var cls:Class;
			trace("Key configuration on ",_target,":");
			for each(var element:XML in _xml.elements()) {
				cls = element.hasOwnProperty("@once")&& Boolean(element.@once.toLowerCase() == "true") ? OnceScanner : SmoothRepeatScanner;
				switch(element.localName()) {
					case "enter":
						char = Keyboard.ENTER;
						trace(element.localName(),"= enter key:", cls);
					break;
					default:
						char = getKeyCode(element.@value);
						trace(element.localName(),"=",String.fromCharCode(char),":", cls);
					break;
				}
				_keyState[char] = new cls(this,element.localName());
			}
		}
		
		private function getKeyCode(value:String):int {
			switch(value) {
				case "enter":
					return Keyboard.ENTER;
				case "Arrow Left":
					return Keyboard.LEFT;
				case "Arrow Right":
					return Keyboard.RIGHT;
				default:
					return value.charCodeAt(0);
			}
		}
		
		private function keyDownHandler(keyEvent:KeyboardEvent):void {
			restartMainFrame();
			if (_keyState[keyEvent.keyCode]!=null) {
				_keyState[keyEvent.keyCode].down();
			}
		}

		private function keyUpHandler(keyEvent:KeyboardEvent):void {
			if (_keyState[keyEvent.keyCode]!=null) {
				_keyState[keyEvent.keyCode].up();
			}
		}
		
		override public function procedureMainFrame():Boolean {
			var ret:Boolean = false;
			var active:Boolean = false;
			for(var label:* in _keyState) {
				ret = _keyState[label].inFrame();
				active ||= ret;
			}
			return active;
		}
		
		override public function afterClose():void {
			super.afterClose();
			_target.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			_target.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
			
		}	
	}
}